package icu.lingjie.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;

public class MyUtil {

    /**
     * 返回指定大小的 int 数组
     */
    public static int[] getIntArrayByKb(int kb){
        return new int[(kb << 10) / 4];
    }

    public static int[] getIntArrayByMb(int mb){
        return new int[(mb << 20) / 4];
    }

    /**
     * 读取文件成 int[]
     */
    public static int[] readIntArrayFromFile(String filePath) {
        File file = new File(filePath);
        int[] intArr = null;
        if (file.exists()) {
            // 1. 根据文件大小创建 int 数组
            long fileLength = file.length();
            intArr = new int[(int) fileLength / 4];
            // 2. 读取文件
            try(RandomAccessFile fin = new RandomAccessFile(file, "r");
                FileChannel fc = fin.getChannel();) {
                MappedByteBuffer buffer = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
                for (int i = 0; i < intArr.length; i++) {
                    intArr[i] = buffer.getInt();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return intArr;
    }

    /**
     * 读取文件成 byte[]
     */
    public static byte[] readByteArrayFromFile(String filePath) {
        File file = new File(filePath);
        byte[] bytes = null;
        if (file.exists()) {
            // 1. 根据文件大小创建 byte 数组
            long fileLength = file.length();
            bytes = new byte[(int) fileLength];
            // 2. 读取文件
            try(FileInputStream fin = new FileInputStream(file);) {
                fin.read(bytes);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bytes;
    }

    /**
     * 读取 JSON 文件成对象
     */
    public static <T> T readJsonObjectFromFile(String filePath, Class<T> valueType) {
        File file = new File(filePath);
        T obj = null;
        if (file.exists()) {
            // 1. 根据文件大小创建 int 数组
            long fileLength = file.length();
            byte[] bytes = new byte[(int) fileLength];
            // 2. 读取文件
            try(RandomAccessFile fin = new RandomAccessFile(file, "r");) {
                fin.read(bytes);
                String str = new String(bytes, StandardCharsets.UTF_8);
                obj = JSON.parseObject(str, valueType);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return obj;
    }

    /**
     * 将 int[] 写入文件
     */
    public static void writeIntArrayToFile(String filePath, int[] intArr) {
        File file = new File(filePath);
        checkOrCreatePath(file.getParentFile().getAbsolutePath());
        try(RandomAccessFile fout = new RandomAccessFile(file, "rw");
            FileChannel fc = fout.getChannel()) {
            // 写入 buffer
            ByteBuffer buffer = ByteBuffer.allocateDirect(intArr.length * 4);
            for (int i = 0; i < intArr.length; i++) {
                buffer.putInt(intArr[i]);
            }
            // 写入文件
            buffer.flip();
            fc.write(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将 byte[] 写入文件
     */
    public static void writeByteArrayToFile(String filePath, byte[] bytes) {
        File file = new File(filePath);
        checkOrCreatePath(file.getParentFile().getAbsolutePath());
        try(FileOutputStream fout = new FileOutputStream(file);) {
            fout.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将对象写入到 JSON 文件
     */
    public static void writeJsonObjectFromFile(String filePath, Object obj) {
        File file = new File(filePath);
        checkOrCreatePath(file.getParentFile().getAbsolutePath());
        // 1. 将字符串转换成 byte 数组
        String str = JSON.toJSONString(obj, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue);
        byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
        // 2. 写入文件
        try(FileOutputStream fout = new FileOutputStream(file)) {
            fout.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 检查路径存不存在，不存在则创建
     */
    public static void checkOrCreatePath(String pathStr) {
        File path = new File(pathStr);
        if ( ! path.exists()) {
            path.mkdirs();
        }
    }

    /**
     * 检查文件是否存在
     */
    public static boolean fileExists(String filePath) {
        File file = new File(filePath);
        return file.exists();
    }


}
